#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <sys/epoll.h>

#define SERVADDR "192.168.101.255"
#define SERVPORT 8888 

int set_socket_nonblocking(int in_i_socket);

int main(int argc, char *argv[])
{
	int sockfd;

	struct sockaddr_in serv_addr;

	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("socket error!");
		return -1;
	}


	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = inet_addr(SERVADDR);
	serv_addr.sin_port = htons(SERVPORT);
	bzero(&(serv_addr.sin_zero),8);

	set_socket_nonblocking(sockfd);

	int i_epoll_handle = epoll_create(1);
	struct epoll_event t_ep_event;	

	t_ep_event.events = EPOLLOUT;
	t_ep_event.data.fd = sockfd;
	epoll_ctl(i_epoll_handle, EPOLL_CTL_ADD, sockfd, &t_ep_event);

	while(true)
	{

		if(-1 == connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr)))
		{
			if(EINTR == errno)
			{
				printf("EINTR catched\n");
			}
			else
			{
				printf("connect error:%s\n", strerror(errno));
			}
		}

		int i_event_num = epoll_wait(i_epoll_handle, &t_ep_event, 1, -1);
		printf("Receive events. number = %d events = %04x\n",
					i_event_num, t_ep_event.events);
		if(t_ep_event.events == EPOLLOUT)
		{
			printf("connect success\n");
			break;
		}
		if(t_ep_event.events == EPOLLIN | EPOLLERR | EPOLLHUP)//11100
		{
			printf("Connect failed\n");
			sleep(3);
			continue;
		}
		if(t_ep_event.events == EPOLLOUT | EPOLLHUP)//10100
		{
			printf("Connect failed\n");
			sleep(3);
			continue;
		}
	}
	
	
	struct sockaddr_in serv_peer;
	socklen_t t_len = sizeof(struct sockaddr);
	getpeername(sockfd, (struct sockaddr*)&serv_peer, &t_len);
	printf("remote ip = [%s]\n", inet_ntoa(serv_peer.sin_addr));

	char buf[512] = {0};
	while(1)
	{
		strncpy(buf, "this is client", 15);
		if(0 >= send(sockfd, &buf, 15, 0))
		{
			printf("send error");
			getpeername(sockfd, (struct sockaddr*)&serv_peer, &t_len);
			printf("remote ip = [%s]\n", inet_ntoa(serv_peer.sin_addr));
			return -1;
		}
		memset(buf,0,512);
		sleep(2);
	}
	close(sockfd);
	return 0;
}

int set_socket_nonblocking(int in_i_socket)
{
	return fcntl(in_i_socket, F_SETFL,
			fcntl(in_i_socket, F_GETFL, 0) | O_NONBLOCK);
}
